import { addMonths, addQuarters, addYears } from "date-fns";
import DateFormatConfig from "../config/date-format-config";
import CommonService from "../services/common-service";
import DynamicElementDataService from "./dynamic-element-data-service";
import DynamicElementDefinition from "./dynamic-element-definition";
import DynamicElementDefinitionConstant from "./dynamic-element-definition-constant";

export default class DynamicElementDataFactory {
  static async queryData(node: DynamicElementDefinition): Promise<any> {
    let result: any;
    
    switch (node.type.toLowerCase()) {
      case DynamicElementDefinitionConstant.cpIndexChart.toLowerCase():
      case DynamicElementDefinitionConstant.cpMarcoChart.toLowerCase():
      case DynamicElementDefinitionConstant.cpMarcoIndustryChart.toLowerCase():
      case DynamicElementDefinitionConstant.cpGlobalMarcoChart.toLowerCase():
        result = await this.queryGeneralChartIndexDataCache1(node);
        break;
      case DynamicElementDefinitionConstant.cpIndexMapChart.toLowerCase():
        result = await this.queryIndexMapPrice1(node);
        break;
      case DynamicElementDefinitionConstant.cpIndexData.toLowerCase():
      case DynamicElementDefinitionConstant.cpMultiIndexData.toLowerCase():
        result = await this.queryIndexMultiPrice1(node, node.config.frequencies[0]);
        break;
    }

    return result;
  }

  /**
   * Queries data with 'CBD_GET_INDEX_FREQUENCY_LIST_1' as objName.
   * @param node 
   */
  static async queryIndexFrequencyList1(): Promise<any> {
    const objectName: string = 'CBD_GET_INDEX_FREQUENCY_LIST_1';

    const orders = [{
      SN: 1,
    }];

    return DynamicElementDataService.queryByObjName(objectName, null, null, orders);
  }

  /**
   * Queries data with 'CBD_GENERAL_CHART_INDEX_DATA_CACHE_1' as objName.
   * @param node 
   */
  private static async queryGeneralChartIndexDataCache1(node: DynamicElementDefinition): Promise<any> {
    const objectName: string = 'CBD_GENERAL_CHART_INDEX_DATA_CACHE_1';
    const filter: string = 'IDX_ID in :IDX_IDS && VALUE_TYPE == 100803 && PUBLISH_DT >= :PUBLISH_DT';
    const indexIDs: any[] = node.config.indexes.map((p: any) => p.IDX_ID);
    const dateString: String = this.getQueryDate(node.config.query);

    // Prepares filter params for query.
    //
    // Example:
    // {
    //     "IDX_IDS": [ // 指标ID集合
    //         120126725,
    //         120013415,
    //         120013414
    //     ],
    //     "PUBLISH_DT": "[2019-10-13]" // 参数为图形组件中传参的查询日期条件即 query 参数配置
    // }
    const filterParams = {
      IDX_IDS: indexIDs,
      PUBLISH_DT: `[${dateString}]`,
    };

    return DynamicElementDataService.queryByObjName(objectName, filter, filterParams);
  }

  /**
   * Queries data with 'CBD_INDEX_MAP_PRICE_1' as objName.
   * @param node 
   */
  private static async queryIndexMapPrice1(node: DynamicElementDefinition): Promise<any> {
    const objectName: string = 'CBD_INDEX_MAP_PRICE_1';
    const filter: string = 'IDX_IDS in :IDX_IDS';
    const indexIDs: any[] = node.config.indexes.map((p: any) => p.IDX_ID);

    // Prepares filter params for query.
    //
    // Example:
    // {
    //     "IDX_IDS": [ // 指标ID集合
    //         120126725,
    //         120013415,
    //         120013414
    //     ]
    // }
    const filterParams = {
      IDX_IDS: indexIDs,
    };

    return DynamicElementDataService.queryByObjName(objectName, filter, filterParams);
  }

  /**
   * Queries data with 'CBD_INDEX_MULTI_PRICE_1' as objName.
   * @param node 
   */
  static async queryIndexMultiPrice1(node: DynamicElementDefinition, frequencyCode: number): Promise<any> {
    const objectName: string = 'CBD_INDEX_MULTI_PRICE_1';
    const filter: string = 'IDX_IDS in :IDX_IDS && FREQUENCY_CODE == :FREQUENCY_CODE';
    const indexIDs: any[] = node.config.indexes.map((p: any) => p.IDX_ID);

    // Prepares filter params for query.
    //
    // Example:
    // {
    // {
    //     "FREQUENCY_CODE": 365,
    //     "IDX_IDS": [
    //         2115030856,
    //         2115030857,
    //         2115030858,
    //         2115030859
    //     ]
    // }
    const filterParams = {
      FREQUENCY_CODE: frequencyCode,
      IDX_IDS: indexIDs,
    };

    return DynamicElementDataService.queryByObjName(objectName, filter, filterParams);
  }

  /**
   * Gets date param for query from query config. 
   * @param queryObject 
   * @returns String of formatted date string. Example: 2020-01-01.
   */
  private static getQueryDate(queryObject: any): string {
    let dateString: string;
    
    if (queryObject.isLatestDate) {
      let dateParam: Date = CommonService.getCurrentDate();
      let duration: number = parseInt(queryObject.date);

      if (queryObject.unit === 1) {
        dateParam = addYears(dateParam, -duration);
      } else if (queryObject.unit === 2) {
        dateParam = addMonths(dateParam, -duration);
      } else if (queryObject.unit === 3) {
        dateParam = addQuarters(dateParam, -duration);
      }

      dateString = CommonService.formatDate(dateParam, DateFormatConfig.shortDateFormat);
    } else {
      dateString = queryObject.date;
    }

    return dateString;
  }
}